<?php
require_once (dirname(__FILE__) . "/../../config.php");
require_once (dirname(__FILE__) . "/../common/db/GenericDao.php");
// product related
require_once (WP_HOME . "/inc/common.php");
require_once (dirname(__FILE__) . "/../../debug.php");
require_once (dirname(__FILE__) . "/../init.php");
?>
<?php

// methods
/*
// Constructor
public function __construct()

// load user
public function loaduser_byemail($email)
public function loaduser_byuid($uid)

// get user information
public function get_uid()
public function get_email()
public function get_password()
public function get_userinfo()
public function get_udata()
public function get_db()
public function get_wids()

// login management
public function login( $email, $password)
public function isAuth()

// user init (after login)
public function standalone_user_init()
public function product_user_init()

// create user
public function create_user( $email, $password = '')

// return user settings (legacy compatible)
public function check_result($pageid)

// error handling
public function isFailed()
public function getErrMessage()
*/
?>
<?php

/*
 * WidgetFramework User
 * Created: 200904 (TT Tsai)
 *
 * User state and data object (login, check, ...)
 *
 * NOTE: please make sure $_SESSION is writable. (Do not call session_write_close() before this)
 */
class WFUser
{
    // main database object
    private $userdb;
    private $username;
    private $password;
    // for user checking
    private $secret = "whatgoesaroundcomesaround";
    // page settings
    private $wids;
    // userinfo
    private $userinfo;
    // authenticated?
    private $auth = false; // true or false
    // error handling
    private $errMessage = "";
    // Constructor
    public function __construct(){
        mydebug_log("[WFUSER] __construct()");

        // check $_SESSION
        if(! isset($_SESSION)){
            mydebug_log("[WFUSER] __construct() Invalid session");
            $this->errMessage = "Invalid session. (probably need session_start())";
            return;
        }
        // create database
        $this->createUserDB();
        if($this->userdb->isFailed()){
            return false;
        }
    }
    //reuse by interface deleteUserByAccount.php
    public function createUserDB(){
        mydebug_log("[WFUSER] createUserDB()");
        // database configurations
        global $wfconf_dbconfig;
        $this->userdb = new WFGenericDao($wfconf_dbconfig["table"]["users"]["name"], $wfconf_dbconfig["table"]["userdata"]["name"], $wfconf_dbconfig, 0);
        if($this->userdb->isFailed()){
            mydebug_log("[WFUSER] createUserDB() create database error");
            $this->errMessage = "database error (init)";
        }else{
            mydebug_log("[WFUSER] createUserDB() is ok");
        }
    }
    // generate checkcode
    public function gencode(){
        mydebug_log("[WFUSER] gencode(): " . md5($this->userinfo['email'] . $this->secret . $this->userinfo['pass']));
        return md5($this->userinfo['email'] . $this->secret . $this->userinfo['pass']);
    }
    // binduser
    public function binduser(){
        mydebug_log("[WFUSER] binduser()");
        $_SESSION['uniqueid'] = $this->gencode();
        $_SESSION['uid'] = $this->userinfo['id'];
        mydebug_log("[WFUSER] binduser() uniqueid: " . $_SESSION['uniqueid']);
        mydebug_log("[WFUSER] binduser() uid: " . $_SESSION['uid']);
        setcookie("un", $_SESSION['uniqueid'], 0, WF_COOKIE_PATH);
        setcookie("userID", $this->userinfo['id'], 0, WF_COOKIE_PATH);
        $lang = isset($_COOKIE['CONSOLE_LANG']) ? $_COOKIE['CONSOLE_LANG'] : $this->userinfo['lang'];
        setcookie("LANG", $lang, 0, WF_COOKIE_PATH);
        mydebug_log("[WFUSER] binduser() cookie un: " . $_SESSION['uniqueid']);
        mydebug_log("[WFUSER] binduser() cookie userID: " . $this->userinfo['id']);
        mydebug_log("[WFUSER] binduser() cookie LANG: " . $this->userinfo['lang']);
        // the final step of binding
        $this->auth = true;
    }
    // load user to this object
    // return: true/false
    public function loaduser_byemail($email){
        mydebug_log("[WFUSER] loaduser_byemail() " . $email);
        // load user
        $uinfolist = $this->userdb->get_users_byemail($email);
        if($this->userdb->isFailed()){
            mydebug_log("[WFUSER] loaduser_byemail() : get_users_byemail failed");
            return false;
        }
        // no exists
        if(! isset($uinfolist[0])){
            mydebug_log("[WFUSER] loaduser_byemail() : get_users_byemail - no user");
            return false;
        }
        // get userinfo
        $this->userinfo = $uinfolist[0];
        mydebug_log("[WFUSER] loaduser_byemail() : ok uid = " . $this->userinfo['id']);
        return true;
    }
    public function loaduser_byuid($uid){
        mydebug_log("[WFUSER] loaduser_byuid() " . $uid);
        // load user
        $uinfolist = $this->userdb->get_users($uid);
        if($this->userdb->isFailed()){
            mydebug_log("[WFUSER] loaduser_byuid() : get_users failed");
            return false;
        }
        // no exists
        if(! isset($uinfolist[0])){
            mydebug_log("[WFUSER] loaduser_byuid() : get_users - no user");
            return false;
        }
        // get userinfo
        $this->userinfo = $uinfolist[0];
        mydebug_log("[WFUSER] loaduser_byuid() : ok mail = " . $this->userinfo['email']);
        return true;
    }
    // get uid
    // return: uid(integer) on success, 0 on fail
    public function get_uid(){
        mydebug_log("[WFUSER] get_uid(): " . $this->userinfo['id']);
        if(isset($this->userinfo['id'])){
            return $this->userinfo['id'];
        }
        return 0;
    }
    // get email
    // return: email(string) on success, false on fail
    public function get_email(){
        mydebug_log("[WFUSER] get_email(): " . $this->userinfo['email']);
        if(isset($this->userinfo['email'])){
            return $this->userinfo['email'];
        }
        return false;
    }
    // get password
    // return: password(string) on success, false on fail
    public function get_password(){
        mydebug_log("[WFUSER] get_password(): " . $this->userinfo['pass']);
        if(isset($this->userinfo['pass'])){
            return $this->userinfo['pass'];
        }
        return false;
    }
    // get userinfo
    // return: userinfo(array) on success, false on fail
    public function get_userinfo(){
        if($this->auth == true && isset($this->userinfo)){
            mydebug_log("[WFUSER] get_userinfo() ok");
            return $this->userinfo;
        }
        mydebug_log("[WFUSER] get_userinfo() failed");
        return false;
    }
    // get udata
    // return: udata(array) on success, false on fail
    public function get_udata(){
        if($this->auth == true && isset($this->userinfo)){
            mydebug_log("[WFUSER] get_userinfo() ok");
            return $this->userdb->get_udata($this->userinfo['id']);
        }
        mydebug_log("[WFUSER] get_userinfo() failed");
        return false;
    }
    // get db
    // return db(object) on success, false on fail
    public function get_db(){
        if($this->auth == true && isset($this->userinfo)){
            mydebug_log("[WFUSER] get_db() ok");
            return $this->userdb;
        }
        mydebug_log("[WFUSER] get_db() failed");
        return false;
    }
    // get wids
    // return: wids(string) on success, "" on fail
    public function get_wids(){
        mydebug_log("[WFUSER] get_wids(): " . $this->wids);
        return $this->wids;
    }
    // login
    // return: true/false
    public function login($email, $password){
        mydebug_log("[WFUSER] login(): " . $email . " " . $password);
        if(false == $this->loaduser_byemail($email)){
            mydebug_log("[WFUSER] login(): load user failed");
            return false;
        }
        if($this->userinfo['pass'] != $password){
            mydebug_log("[WFUSER] login(): password mismatch");
            return false;
        }
        // login ok
        mydebug_log("[WFUSER] login(): ok");
        $this->binduser();
        return true;
    }
    // isAuth
    // return: true/false
    public function isAuth(){
        mydebug_log("[WFUSER] isAuth(): " . $this->auth);
        return $this->auth;
    }
    // recover session
    // return: true/false
    private function recover_session(){
        mydebug_log("[WFUSER] recover_session()");
        // check is the user session exist?
        if(! isset($_SESSION['uniqueid'])){
            mydebug_log("[WFUSER] recover_session(): session uniqueid isn't set");
            return false;
        }
        // yes, try to compare
        if($_SESSION['uniqueid'] != $this->gencode()){
            // session invalid
            mydebug_log("[WFUSER] recover_session(): code mismatch");
            return false;
        }
        $this->binduser();
        return true;
    }
    public function recover_session_byemail($email){
        mydebug_log("[WFUSER] recover_session_byemail() " . $email);
        if(false == $this->loaduser_byemail($email)){
            mydebug_log("[WFUSER] recover_session_byemail() failed");
            return false;
        }
        return $this->recover_session();
    }
    public function recover_session_byuid($uid){
        mydebug_log("[WFUSER] recover_session_byuid() " . $uid);
        if(false == $this->loaduser_byuid($uid)){
            mydebug_log("[WFUSER] recover_session_byuid() failed");
            return false;
        }
        return $this->recover_session();
    }
    public function standalone_user_init(){
        mydebug_log("[WFUSER] standalone_user_init()");
        if(isset($_COOKIE['userID'])){
            return $this->recover_session_byuid($_COOKIE['userID']);
        }
        mydebug_log("[WFUSER] standalone_user_init(): cookie userID isn't set");
        return false;
    }
    public function product_user_init(){
        mydebug_log("[WFUSER] product_user_init()");
        $email = product_get_session_username();
        if(false == $this->recover_session_byemail($email)){
            // no previous session
            mydebug_log("[WFUSER] product_user_init(): no previous session");
            // load user
            if(false == $this->loaduser_byemail($email)){
                // create the user
                mydebug_log("[WFUSER] product_user_init(): create user");
                if(! $this->create_user($email)){
                    mydebug_log("[WFUSER] product_user_init(): create user failed");
                    $this->errMessage .= "creating user failed";
                    return false;
                }
            }
            $this->binduser();
            // create cookies for page
            $this->createCookieForPage();
        }
        mydebug_log("[WFUSER] product_user_init(): ok");
        return true;
    }
    // create user
    // return: true/false
    public function create_user($email, $password = ''){
        mydebug_log("[WFUSER] create_user() " . $email . " " . $password);
        global $wfconf_default_user_cdata;
        global $wfconf_default_user_udata;
        global $wfconf_default_user_pdata;
        global $wfconf_default_user_lang;
        global $wfconf_default_user_theme;
        $newuser = array();
        $newuser["email"] = $email;
        $newuser["pass"] = $password;
        $newuser["data"] = "";
        $newuser["cdata"] = $wfconf_default_user_cdata;
        $newuser["udata"] = $wfconf_default_user_udata;
        $newuser["pdata"] = $wfconf_default_user_pdata;
        $newuser["lang"] = $wfconf_default_user_lang;
        $newuser["theme"] = $wfconf_default_user_theme;
        $jsonDataContainer = $wfconf_default_user_cdata;
        WF::getControllerFactory()->getDbController()->insertOrUpdateContainerByJsonData($jsonDataContainer);
        // add users
        $this->userdb->add_users($newuser);
        if($this->userdb->isFailed()){
            $this->errMessage = "(adding user) " . $this->userdb->getErrMessage();
            mydebug_log("[WFUSER] create_user() added user failed " . $this->userdb->getErrMessage());
            return false;
        }
        //set default widget data
        $this->userdb->set_default_widgetdata($email, $wfconf_default_user_udata);
        mydebug_log("[WFUSER] create_user() ok");
        // try to load again
        return $this->loaduser_byemail($email);
    }
    // check result
    // return: udata(array) on success, false on fail
    public function check_result($pageid, $cid){
        mydebug_log("[WFUSER] check_result() pageid: " . $pageid);
        // check auth
        if($this->auth == false){
            $this->errMessage = "auth is false";
            return false;
        }
        // make udata
        $udata = $this->get_udata();
        // pageid
        if($pageid == 0){
            $pageid = 9999;
            // find smallest pageid
            if(is_array($udata) && $udata){
                foreach($udata as $uinfo){
                    if($uinfo['page'] < $pageid){
                        $pageid = $uinfo['page'];
                    }
                }
            }
            mydebug_log("[WFUSER] check_result() pageid chaged to: " . $pageid);
        }
        $arrUdata = array();
        if(is_array($udata) && $udata){
            foreach($udata as $winfo){
                if($winfo['page'] == $pageid){
                    $arrUdata[] = $winfo;
                }
            }
        }
        // lastID
        $lastID = $this->userdb->get_last_userdata_id($this->userinfo['id']);
        mydebug_log("[WFUSER] check_result() lastID: " . $lastID);
        setcookie("lastID", $lastID, 0, WF_COOKIE_PATH);
        // make pdata
        //$pdataobj = json_decode($this->userinfo['pdata'], true);
        // response
        $arrResponse = array();
        
        $intContainerId = $cid;
        $intUserId = $_SESSION['uid'];
        $arrsUdata = WF::getControllerFactory()->getDbController()->getArrsUserdataByCondition($intContainerId, $intUserId);
        
        $intContainerId = $cid;
        $jsonPdata = $this->userinfo['pdata'];
        $arrsPdata = WF::getControllerFactory()->getDbController()->getArrsPdataByContainerIdAndJsonPdata($intContainerId, $jsonPdata);
        
        //$arrResponse["udata"] = $arrUdata;
        //$arrResponse["pdata"] = $pdataobj;
        $arrResponse["udata"] = $arrsUdata;
        $arrResponse["pdata"] = $arrsPdata;
        $arrResponse["lang"] = $this->userinfo['lang'];
        $arrResponse["theme"] = $this->userinfo['theme'];
        $arrResponse["lastID"] = $lastID;
        return $arrResponse;
    }
    // createCookieForPage
    // return: true/false
    public function createCookieForPage(){
        mydebug_log("[WFUSER] createCookieForPage()");
        if($this->auth == false){
            $this->errMessage = "auth is false";
            return false;
        }
        // get data from userdata
        $winfolist = $this->userdb->get_userdata(null, $this->userinfo['id']);
        if($this->userdb->isFailed()){
            $this->errMessage = "database error (get_userdata)";
            return false;
        }
        // get udata
        $udata = $this->get_udata();
        // find smallest pageid
        $pageid = 9999;
        if(isset($_COOKIE['lastTab'])){
            $pageid = $_COOKIE['lastTab'];
        }else{
            // find smallest pageid
            foreach($udata as $uinfo){
                if($uinfo['page'] < $pageid){
                    $pageid = $uinfo['page'];
                }
            }
        }
        $ckstr = "";
        foreach($udata as $uinfo){
            if($uinfo['page'] == $pageid){
                $ckstr .= $uinfo['modname'] . ",";
            }
        }
        $this->wids = $ckstr;
        setcookie("wids", $ckstr, 0, WF_COOKIE_PATH);
        mydebug_log("[WFUSER] createCookieForPage() wids: " . $this->wids);
    }
    public function getUserGeneratedInfoOfWidget(){
        return WF::getWidgetPoolFactory()->getWidgetPoolDB()->getUserGeneratedInfoOfWidget();
    }
    public function deleteUserByAccount($account){
        mydebug_log("[WFUSER] deleteUserByAccount() account:".$account);
        if(false == $this->loaduser_byemail($account)){
            mydebug_log("[WFUSER] deleteUserByAccount(): load user failed");
            return false;
        }

        $this->userdb->del_users($this->userinfo['id']);
        if($this->userdb->isFailed()){
            mydebug_log("[WFUSER] deleteUserByAccount(): ".$this->errMessage);
            return false;
        }
        $this->userdb->del_userdata_byuid($this->userinfo['id']);
        if($this->userdb->isFailed()){
            mydebug_log("[WFUSER] deleteUserByAccount(): ".$this->errMessage);
            return false;
        }
        mydebug_log("[WFUSER] deleteUserByAccount() ok");
        return true;
    }
    /*
	 * Error handling
	 */
    public function isFailed(){
        if($this->errMessage != ""){
            return TRUE;
        }
        return FALSE;
    }
    public function getErrMessage(){
        return $this->errMessage;
    }
}